import Taro from "@tarojs/taro";
import { post } from "./request/request";
import {
  getLocalToken,
  setLocalToken,
  clearLocalToken,
  setLocalUserInfo,
  getLocalUserInfo,
} from "./userInfo";
import apiUrl from "./urls";
import { Loading, Storage } from "./tools/public";
import { envConfig } from "./config/index";
import { handleStore } from "./init";
import { USERINFO, LOGIN_TOKEN_KEY,BINDSTAFFCARDID,ISBINDSTAFF } from "../constants/userInfo";

let timer = null;
let promise = null;
let wxCode = null;

function getCode() {
  // console.log('准备预加载code')
  wxCode = null;
  clearTimeout(timer);

  promise = new Promise((resolve, reject) => {
    const l = () => {
      Taro.login({
        complete(res) {
          const code = res.code;
          if (code) {
            wxCode = code;
            // 成功若是没被使用则废弃 五分钟后重新获取
            clearTimeout(timer);
            timer = setTimeout(getCode, 5 * 60 * 1000);
            // console.log('预加载code成功', code)
            resolve(code);
            return;
          }

          // 失败重试
          l();
        },
      });
    };
    l();
  });
}
getCode();

// 获取code
function loginByWechat() {
  // 如果有缓存的code 直接使用 并立即生成新code备用
  if (wxCode) {
    const code = wxCode;
    getCode();
    return Promise.resolve(code);
  }

  // 如果没有备用code
  return new Promise((resolve, reject) => {
    if (!promise) getCode();

    promise.then(
      (code) => {
        getCode();
        resolve(code);
      },
      (error) => reject(error)
    );
  });
}

// 自動登錄
function autoLogin() {
  return new Promise((resolve, reject) => {
    Taro.getSetting({
      success: (res) => {
        if (!res.authSetting["scope.userInfo"]) {
          resolve({
            logined: true,
            authed: false,
          });
          return;
        }

        loginByWechat()
          .then((code) => {
            Taro.getUserInfo({
              // withCredentials: true,
              desc: "用于完善用户资料",
              success: (r) => {
                const { encryptedData, iv, userInfo } = r;
                authUserInfo(code, encryptedData, iv, userInfo)
                  .then(() =>
                    resolve({
                      logined: true,
                      authed: true,
                    })
                  )
                  .catch(() => {});
              },
              fail: () =>
                resolve({
                  logined: true,
                  authed: false,
                }),
            });
          })
          .catch(() =>
            resolve({
              logined: true,
              authed: false,
            })
          );
      },
      fail: () =>
        resolve({
          logined: true,
          authed: false,
        }),
    });
  });
}
// 尝试静默登录
function pureLogin() {
  return new Promise((resolve, reject) => {
    function l(retryCount) {
      // 重试超过三次停止重试
      if (retryCount <= 0) {
        reject(new Error("登录异常"));
        return;
      }

      loginByWechat()
        .then((code) => {
          silentLogin(code)
            .then(() => resolve(autoLogin()))
            .catch(() => l(--retryCount));
        })
        .catch(() => login(--retryCount));
    }

    l(3);
  });
}

// 尝试刷新Token
function updateToken(authorizePhone) {
  
  // 如果是授权手机号刷新token的话，需要传一个参数给后台。因为后台逻辑写的乱七八糟
  // 获得本地Token并清空
  const localToken = getLocalToken();
  const localUserInfo = getLocalUserInfo();
  clearLocalToken();

  // 缺少登录信息 自动登录
  if (!localToken || !localUserInfo) return pureLogin();

  // 刷新Token
  return new Promise((resolve, reject) => {
    loginByWechat()
      .then((code) => {
        refreshToken(code, envConfig.companyId, localToken, authorizePhone)
          .then(() => resolve())
          .catch(() => resolve(pureLogin()));
      })
      .catch(() => reject(new Error("获取微信Code失败")));
  });
}

let userInfo = null;

function login() {
  return new Promise((resolve, reject) => {
    if (userInfo) {
      resolve(userInfo);
      return;
    }

    Loading.show("正在授权...");
    updateToken()
      .then(() => {
        const localUserInfo = getLocalUserInfo();
        userInfo = localUserInfo;
        Loading.hide();
        resolve(localUserInfo);
      })
      .catch((error) => {
        console.log("登录异常", error);
        Loading.hide();
        reject(error);
      });
  });
}
// 刷新授权Token
function refreshToken(code, companyId, localToken, authorizePhone) {
  return new Promise((resolve, reject) => {
    post(
      apiUrl.refreshTokenUrl,
      {
        code,
        companyId,
        token: localToken,
        authorizePhone: authorizePhone || "0",
      },
      {
        silentFail: true,
        withToken: false,
      }
    ).then(
      (data ) => {
        if (!data || !data.token) {
          reject(data);
          return;
        }

        let u = getLocalUserInfo();
        u = { ...data };
        if (!("isAuthUserInfo" in u)) {
          u.isAuthUserInfo = true;
          setLocalUserInfo(u, 1);
        }

        handleStore(USERINFO,u);
        if (u.gov && authorizePhone) {
          handleStore(ISBINDSTAFF,true); 
          handleStore(BINDSTAFFCARDID,u.cardId); 
          Storage.setSync("isBindStaff", true);
          Storage.setSync("bindStaffCardId", u.cardId);
        }
        const token = data.token;
        handleStore(LOGIN_TOKEN_KEY,token);
        setLocalToken(token);
        resolve(token);
      },
      (error) => {
        reject(error);
      }
    );
  });
}

// 同步用户信息授权到服务器
function authUserInfo(code, encryptedData, iv, userInfos, cardId = null) {
  return new Promise((resolve, reject) => {

    userInfos.isAuthUserInfo = true;
    const localUserInfo = getLocalUserInfo();
    const newUserInfo = {
      ...localUserInfo,
      ...userInfos,
    };
    handleStore(USERINFO,newUserInfo);
    setLocalUserInfo(newUserInfo, 1);

    resolve(newUserInfo);
    post(apiUrl.loginUrl, {
      code,
      encryptedData,
      iv,
      userInfos,
      companyId: envConfig.companyId,
      cardId,
    }).then(
      (res) => {
        console.log(res);
      },
      (res) => {
        console.log(res);
      }
    );
  });
}
// 通过code自动登录
function silentLogin(code) {
  return new Promise((resolve, reject) => {
    post(
      apiUrl.pureLoginUrl,
      {
        code,
        companyId: envConfig.companyId,
      },
      {
        silentFail: true,
        withToken: false
      }
    ).then(
      (data) => {
        const u = {
          unionId: data.unionId,
          openId: data.openId,
          nickName: data.nickName,
          gov: data.gov,
          depId: data.depId,
          depName: data.depName,
          depPage: data.depPage,
          realName: data.realName || "",
          cardNumber: data.cardNumber,
          unitId: data.unitId,
          unitName: data.unitName,
          province: data.province || "",
          gender: data.gender,
          userId: data.userId,
          token: data.token,
          avatarUrl: data.avatarUrl,
          isAuthUserInfo: false,
        };
        
        handleStore(USERINFO,u);
        handleStore(LOGIN_TOKEN_KEY,data.token);
        setLocalToken(data.token);
        setLocalUserInfo(u, 1);
 
        resolve(data);
      },
      (error) => {
        reject(error);
      }
    );
  });
}
export default authUserInfo;

export { login, loginByWechat, updateToken };
